package pkg60311assign3;

import java.util.Calendar;
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class test_userProfiler {
    @Test
	public void testIsValidNameIsNull() {
		assertFalse(userProfiler.isValidName(null));
	}

	@Test
	public void testIsValidNameIsEmpty() {
		assertFalse(userProfiler.isValidName(""));
	}
	
	@Test
	public void testIsValidNameIsNonAlphaString() {
		assertFalse(userProfiler.isValidName("1"));
	}

	@Test
	public void testIsValidNameIsString() {
		assertTrue(userProfiler.isValidName("A"));
	}

	@Test
	public void testIsValidMiddleNameNull() {
		assertTrue(userProfiler.isValidMiddleName(null));
	}
	
	@Test
	public void testIsValidMiddleNameEmpty() {
		assertFalse(userProfiler.isValidMiddleName(""));
	}

	@Test
	public void testIsValidMiddleNameNumber() {
		assertFalse(userProfiler.isValidMiddleName("1"));
	}

	@Test
	public void testIsValidMiddleNameString() {
		assertTrue(userProfiler.isValidMiddleName("A"));
	}

	@Test
	public void testConvertHeightToCmInch() {
            double actual = userProfiler.convertHeightToCm(0, 1);
            double expected =2.54;
            assertEquals("Result", expected, actual, 0.01);
	}

	@Test
	public void testConvertHeightToCmFoot() {
            double expected = 30.48;
            double actual = userProfiler.convertHeightToCm(1, 0);
            assertEquals("Result", expected, actual, 0.01);
	}
	
	@Test
	public void testConvertHeightToCmNullFoot() {
		assertEquals("Result", 2.54, userProfiler.convertHeightToCm(null, 1), 0.01);
	}

	@Test
	public void testConvertHeightToCmNullInch() {
		double x = 2.54*12;
		assertEquals("Result", x, userProfiler.convertHeightToCm(1, null), 0.01);
	}

	@Test
	public void testConvertHeightToCmNullBoth() {
		assertEquals("Result", 0, userProfiler.convertHeightToCm(null, null), 0.01);
	}

	@Test
	public void testIsValidHeightTooShort() {
		assertFalse(userProfiler.isValidHeight(-1));
	}

	@Test
	public void testIsValidHeightTooTall() {
		assertFalse(userProfiler.isValidHeight(10000));
	}

	@Test
	public void testIsValidHeight() {
		assertTrue(userProfiler.isValidHeight(175));
	}

	@Test
	public void testConvertWeightToKgUnit() {
		assertEquals("Result", 1.0, userProfiler.convertWeightToKg(2.20462262185), 0.01);
	}

	@Test
	public void testConvertWeightToKg() {
		assertEquals("Result", 10.0, userProfiler.convertWeightToKg(22.0462262185), 0.01);
	}

	@Test
	public void testIsValidWeightIsTooLight() {
		assertFalse(userProfiler.isValidWeight(-1.0));
	}

	@Test
	public void testIsValidWeightIsTooHeavy() {
		assertFalse(userProfiler.isValidWeight(10000.0));
	}

	@Test
	public void testIsValidWeight() {
		assertTrue(userProfiler.isValidWeight(45.0));
	}
	
	@Test
	public void testIsValidBirthdateTooYoung() {
		Calendar c = Calendar.getInstance();
		assertFalse(userProfiler.isValidBirthdate(c));
	}

	@Test
	public void testIsValidBirthdateTooOld() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, 1820);
		assertFalse(userProfiler.isValidBirthdate(c));
	}

	@Test
	public void testIsValidBirthdate() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, 1978);
		assertTrue(userProfiler.isValidBirthdate(c));
	}
	
	@Test
	public void testIsValidBirthdateNull() {
		assertFalse(userProfiler.isValidBirthdate(null));
	}

	@Test
	public void testIsValidBirthdateFeb29TooYoung() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, 2008);
		c.set(Calendar.MONTH, 2);
		c.set(Calendar.DAY_OF_MONTH, 29);
		assertFalse(userProfiler.isValidBirthdate(c));
	}

	@Test
	public void testIsValidBirthdateFeb29TooOld() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, 4);
		c.set(Calendar.MONTH, 2);
		c.set(Calendar.DAY_OF_MONTH, 29);
		assertFalse(userProfiler.isValidBirthdate(c));
	}

	@Test
	public void testIsValidBirthdateFeb29() {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, 1988);
		c.set(Calendar.MONTH, 2);
		c.set(Calendar.DAY_OF_MONTH, 29);
		assertTrue(userProfiler.isValidBirthdate(c));
	}

	@Test
	public void testCreateGUIDNewYear() {
		File f = new File("./guid.bin");
		String outString = "2010.9903";
		Calendar cNow = Calendar.getInstance();
		String s = new String();
		s += cNow.get(Calendar.YEAR) + ".0001";

		try 
		{
			
			if (!f.exists()) f.createNewFile();
			FileWriter out = new FileWriter(f);
			if (!f.canWrite())
			{
				System.out.println("Waiting on guid.bin to be available for writing.");
				while(!f.canWrite());
			}
			out.write(outString.toCharArray());
			out.flush();
			out.close();
				
		} catch (Exception e) {
			System.err.println("[testCreateGUIDNewYear] Writing to guid.bin failed\n\t=> " + e.getMessage());
			fail("Woops");
		}
		
		try
		{
			assertEquals("Result", s, userProfiler.createGUID());

		} catch (Exception e) {
			System.err.println("[testCreateGUIDNewYear] assertEquals failed\n\t=> " + e.getMessage());
		}

	}
	
	@Test
	public void testCreateGUID() {
		try {
			char[] fChars = new char[4];
			char[] sChars = new char[4];
			char[] tChars = new char[4];

			String first = userProfiler.createGUID();
			String second = userProfiler.createGUID();
			String third = userProfiler.createGUID();

			first.getChars(5, 9, fChars, 0);
			second.getChars(5, 9, sChars, 0);
			third.getChars(5, 9, tChars, 0);

			Integer f = Integer.parseInt(new String(fChars).trim());
			Integer s = Integer.parseInt(new String(sChars).trim());
			Integer t = Integer.parseInt(new String(tChars).trim());
				
			assertTrue((s-f)==1 && (t-s)==1);
		} catch (Exception e) {
			fail("Woops");
		}
				
	}
	
	@Test
	public void testCreateGUIDNoFile() {
		try
		{
			Calendar cNow = Calendar.getInstance();
			String s = new String();
			s += cNow.get(Calendar.YEAR) + ".0001";
			
			File f = new File("./guid.bin");
			if (f.exists()) f.delete();

			assertEquals("Result", s, userProfiler.createGUID());
		} catch (Exception e) {
			fail("Woops");
		}
	}
	
	@Test
	public void testCreateGUIDCapacity() {
		File f = new File("./guid.bin");
		Calendar cNow = Calendar.getInstance();
		String s = new String();
		s += cNow.get(Calendar.YEAR) + ".9999";

		try 
		{
			
			if (!f.exists()) f.createNewFile();
			FileWriter out = new FileWriter(f);

			out.write(s.toCharArray());
			out.flush();
			out.close();
				
		} catch (Exception e) {
			System.err.println("[testCreateGUIDCapacity] Writing to guid.bin failed\n\t=> " + e.getMessage());
			fail("Woops");
		}
		try
		{
			userProfiler.createGUID();
		} catch (IOException e) {
			assertTrue(e.getMessage().equals("Out of GUIDs for this year."));
		} catch (Exception e) {
			fail("Woops");
		}
	}   

        @Test
	public void testIsValidDateateNull() {
		assertFalse(userProfiler.isValidDate(null));
	}

        @Test
	public void testIsValidDateateReal() {
		assertTrue(userProfiler.isValidDate("2008-02-29"));
	}

        @Test
	public void testIsValidDateateNotReal() {
		assertFalse(userProfiler.isValidDate("2009-02-29"));
	}

}
